package com.webchat.connect.messagequeue.consumer.service;


import com.webchat.common.constants.ConnectConstants;
import com.webchat.common.enums.AccountRelationTypeEnum;
import com.webchat.common.enums.ChatMessageTypeEnum;
import com.webchat.common.enums.messagequeue.MessageQueueEnum;
import com.webchat.common.service.FreeMarkEngineService;
import com.webchat.common.service.messagequeue.producer.MessageQueueProducer;
import com.webchat.common.util.JsonUtil;
import com.webchat.connect.service.AccountService;
import com.webchat.connect.service.MessageCardTemplateService;
import com.webchat.connect.websocket.handler.ChatWebSocketEndPointServletHandler;
import com.webchat.domain.dto.messagecard.MessageCardSendDTO;
import com.webchat.domain.vo.request.mess.ChatMessageRequestVO;
import com.webchat.domain.vo.response.MessageCardTemplateResponseVO;
import com.webchat.domain.vo.response.mess.ChatMessageResponseVO;
import com.webchat.rmi.pgc.MessageCardTemplateClient;
import freemarker.template.TemplateException;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.webchat.common.enums.ChatMessageTypeEnum.SERVER_ACCOUNT_MESSAGE_CARD;

@Service
public class MessageCardPushConsumeService {


    private static final Logger log = LoggerFactory.getLogger(MessageCardPushConsumeService.class);

    @Autowired
    private MessageCardTemplateService messageCardTemplateService;

    @Autowired
    private FreeMarkEngineService freeMarkEngineService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private MessageQueueProducer<ChatMessageRequestVO, Long> messageQueueProducer;

    /**
     * 服务号消息卡片推送消费
     *
     * @param message
     */
    public void consume(String message) {

        MessageCardSendDTO messageCard = JsonUtil.fromJson(message, MessageCardSendDTO.class);
        String account = messageCard.getSender();
        String receiver = messageCard.getReceiver();
        Set<String> receivers = messageCard.getReceivers();
        if (receivers == null) {
            receivers = new HashSet<>();
            receivers.add(receiver);
        }
        /**
         * 基于模版引擎渲染消息卡
         */
        Map<String, Object> vars = messageCard.getVars();
        // 查询推送消息模版配置
        String templateId = messageCard.getTemplateId();
        MessageCardTemplateResponseVO template = messageCardTemplateService.get(templateId);
        if (template == null) {
            return;
        }

        // 判断是否订阅服务号
        Map<String, Boolean> isSubscribeMap = accountService.batchIsSubscribe(
                                                        new ArrayList<>(receivers),
                                                        account,
                                                        AccountRelationTypeEnum.USER_SERVER);
        if (MapUtils.isEmpty(isSubscribeMap)) {
            return;
        }

        List<String> pushUsers = isSubscribeMap.entrySet().stream()
                                .filter(entry -> ObjectUtils.equals(entry.getValue(), true))
                                .map(entry -> entry.getKey())
                                .toList();

        /**
         * 渲染消息卡内容
         */
        String messageCardTemplateContent = null;
        try {
            messageCardTemplateContent = freeMarkEngineService.getContent(template.getContent(), vars);
        } catch (Exception e) {
            log.error("服务号消息卡模版内容引擎渲染异常 =====> template:{}, vars:{}",
                    template.getContent(), JsonUtil.toJsonString(vars));
            return;
        }

        MessageCardTemplateResponseVO messageExt = new MessageCardTemplateResponseVO();
        messageExt.setLogo(messageCard.getLogo());
        messageExt.setTitle(messageCard.getTitle());
        messageExt.setContent(messageCardTemplateContent);
        messageExt.setRedirectName(messageCard.getRedirectName());
        messageExt.setRedirectUrl(messageCard.getRedirectUrl());

        ChatMessageResponseVO<MessageCardTemplateResponseVO> chatMessageResponseVO = new ChatMessageResponseVO();
        chatMessageResponseVO.setSenderId(account);
        chatMessageResponseVO.setType(SERVER_ACCOUNT_MESSAGE_CARD.getType());
        chatMessageResponseVO.setMessageExt(messageExt);
        Set<String> bizCodes = ConnectConstants.ConnectBiz.getBizCode(ConnectConstants.BizEnum.CHAT);
        for (String bizCode : bizCodes) {
            for (String pushUser : pushUsers) {
                WebSocketSession webSocketSession = ChatWebSocketEndPointServletHandler.getSession(bizCode, pushUser);
                if (webSocketSession == null || !webSocketSession.isOpen()) {
                    continue;
                }
                try {
                    webSocketSession.sendMessage(new TextMessage(JsonUtil.toJsonString(chatMessageResponseVO)));
                    /**
                     *  持久化服务号消息卡数据
                     */
                    this.persistentArticlePushMessage(account, pushUser, message);
                } catch (IOException e) {
                    // TODO
                }
            }
        }
    }

    /**
     * 公众号推送消息持久化
     *
     */
    private void persistentArticlePushMessage(String serverAccount, String userId, String message) {

        ChatMessageRequestVO persistentMessage = new ChatMessageRequestVO();
        persistentMessage.setType(ChatMessageTypeEnum.SERVER_ACCOUNT_MESSAGE_CARD.getType());
        persistentMessage.setSenderId(serverAccount);
        persistentMessage.setReceiverId(userId);
        persistentMessage.setMessage(message);
        /**
         * 走统一的消息持久化处理服务（服用了对话场景持久化服务）
         *
         */
        messageQueueProducer.send(MessageQueueEnum.QUEUE_PERSISTENT_MESSAGE, persistentMessage);
    }
}
